import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router';

/**
 * 路由复用逻辑:当路由配置使用 data: {routeReuseStrategy: true},那么当路由从子页面回到此页面,则使用路由缓存,其他路由跳转方法则不使用路由缓存
 */
export class KylinRouteReuseStrategy implements RouteReuseStrategy {
    public static handlers: { [key: string]: DetachedRouteHandle } = {};

    /**
     * 删除缓存路由快照的方法
     */
    public static deleteRouteSnapshot(path: string): void {
        const name = path.replace(/\//g, '_');
        if (KylinRouteReuseStrategy.handlers[name]) {
            delete KylinRouteReuseStrategy.handlers[name];
        }
    }

    /**
     * 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断
     */
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        return !!route.data.routeReuseStrategy;
    }

    /**
     * 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象
     */
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        if (route.data.routeReuseStrategy) {
            KylinRouteReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
        }
    }

    /**
     * path 在缓存中有的都认为允许还原路由
     */
    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return !!KylinRouteReuseStrategy.handlers[this.getRouteUrl(route)];
    }

    /**
     * 从缓存中获取快照，若无则返回nul
     */
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
        if (!route.routeConfig) {
            return null;
        }

        if (route.routeConfig.loadChildren) {
            return null;
        }

        if (!KylinRouteReuseStrategy.handlers[this.getRouteUrl(route)]) {
            return null;
        }
        return KylinRouteReuseStrategy.handlers[this.getRouteUrl(route)];
    }

    /**
     * 进入路由触发，判断是否同一路由
     */
    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig && JSON.stringify(future.params) === JSON.stringify(curr.params);
    }

    /**
     * 使用route的path作为快照的key
     */
    getRouteUrl(route: ActivatedRouteSnapshot) {
        return route['_routerState'].url.replace(/\//g, '_');
    }

}
